package com.jf.blog_jf04.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jf.blog_jf04.bean.*;
import com.jf.blog_jf04.data.PageInfo;
import com.jf.blog_jf04.data.dto.UserinfoDto;
import com.jf.blog_jf04.data.ov.*;
import com.jf.blog_jf04.mapper.UserinfoMapper;
import com.jf.blog_jf04.service.*;
import com.jf.blog_jf04.utils.BeanConvertUtils;
import com.jf.blog_jf04.utils.LoginUtils;
import com.jf.blog_jf04.utils.MyConstants;
import com.jf.blog_jf04.utils.R;
import com.jf.blog_jf04.utils.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author pang6
 * @description 针对表【userinfo(用户表)】的数据库操作Service实现
 * @createDate 2025-10-18 14:32:11
 */
@Service
@Transactional
public class UserinfoServiceImpl extends ServiceImpl<UserinfoMapper, Userinfo>
        implements UserinfoService {

    @Value("${userinfo.default.password}")
    private String userinfoDefaultPassword;
    @Value("${userinfo.default.avatar}")
    private String userinfoDefaultAvatar;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private KaptchaService kaptchaService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private TagService tagService;
    @Autowired
    private BlogService blogService;
    @Autowired
    private BlogTagService blogTagService;
    @Autowired
    private CommentService commentService;


    @Override
    public R login(LoginOV form) {
        if (!kaptchaService.checkKaptcha(form.getUuid(), form.getCode())) {
            throw new BusinessException("验证码不正确！");
        }
        Userinfo userinfo = this.getUserinfoByUsername(form.getUsername());
        if (userinfo == null) {
            throw new BusinessException("用户名或密码不正确！");
        }
        String slatPassword = LoginUtils.createPassword(form.getPassword(), userinfo.getSlat());
        if (!slatPassword.equals(userinfo.getPassword())) {
            throw new BusinessException("用户名或密码不正确！");
        }
        if (userinfo.getStatus() == 2) {
            throw new BusinessException("用户已封禁，请联系管理员");
        }
        String token = LoginUtils.createToken();
        redisTemplate.opsForValue().set(MyConstants.TOKEN_KEY + token, userinfo.getUserinfoId().toString(), Duration.ofDays(30));
        return R.success().put(MyConstants.TOKEN_NAME, token);
    }

    @Override
    public void saveOrUpdate(UserinfoUpdateOV form) {
//        Userinfo userinfo = new Userinfo();
//        userinfo.setUserinfoId(form.getUserinfoId());
//        userinfo.setUsername(form.getUsername());

//        BeanUtils.copyProperties(form, userinfo);

        Userinfo userinfo = BeanConvertUtils.copyBean(form, Userinfo.class);

        if (userinfo.getUserinfoId() == null) {
            if (getUserinfoByUsername(userinfo.getUsername()) != null) {
                throw new BusinessException("用户名已存在！");
            }
            if (getUserinfoByPhone(userinfo.getPhone()) != null) {
                throw new BusinessException("手机号已存在！");
            }
            if (getUserinfoByHref(userinfo.getHref()) != null) {
                throw new BusinessException("个性域名已存在！");
            }
            userinfo.setRoleId(MyConstants.ROLE_ADMIN);
            userinfo.setSlat(LoginUtils.getSlat());
            userinfo.setPassword(LoginUtils.createPassword(userinfoDefaultPassword, userinfo.getSlat()));
            userinfo.setUserinfoStatus(MyConstants.USERINFO_YIRENZHENG);
            if (!StringUtils.hasText(userinfo.getAvatar())) {
                userinfo.setAvatar(userinfoDefaultAvatar);
            }
            this.save(userinfo);
        } else {
            /*修改时运行用户名和原值一致(不修改用户名的情况)*/
            Userinfo search = this.getOne(new QueryWrapper<Userinfo>()
                    .eq("username", userinfo.getUsername())
                    .ne("userinfo_id", userinfo.getUserinfoId())
            );
            if (search != null) {
                throw new BusinessException("用户名已存在");
            }
            search = this.getOne(new QueryWrapper<Userinfo>()
                    .eq("phone", userinfo.getPhone())
                    .ne("userinfo_id", userinfo.getUserinfoId())
            );
            if (search != null) {
                throw new BusinessException("手机号已存在！");
            }
            search = this.getOne(new QueryWrapper<Userinfo>()
                    .eq("href", userinfo.getHref())
                    .ne("userinfo_id", userinfo.getUserinfoId())
            );
            if (search != null) {
                throw new BusinessException("个性域名已存在！");
            }
            this.updateById(userinfo);
        }
    }

    @Override
    public void delete(List<Integer> ids) {
        if (ids.contains(MyConstants.ADMIN_ID)) {
            throw new BusinessException("超级管理员禁止删除！");
        }
        this.removeByIds(ids);
        /*如果设计表的时候，存在外键约束，则无需下列代码*/
        categoryService.remove(new QueryWrapper<Category>().in("create_user", ids));
        tagService.remove(new QueryWrapper<Tag>().in("create_user", ids));
        List<Blog> blogList = blogService.list(new QueryWrapper<Blog>().in("create_user", ids));
        List<Integer> blogIds = blogList.stream().map(Blog::getBlogId).collect(Collectors.toList());
        if (!blogList.isEmpty()) {
            blogService.removeByIds(blogIds);
            blogTagService.remove(new QueryWrapper<BlogTag>().in("blog_id", blogIds));
            commentService.remove(new QueryWrapper<Comment>().in("blog_id", blogIds));
        }
    }

    @Override
    public R getPage(PageInfo pageInfo, UserinfoSearchOV form) {
        IPage<Userinfo> iPage = this.page(pageInfo.setPage(), new QueryWrapper<Userinfo>()
                .eq("role_id", form.getRoleId())
                .eq(form.getUserinfoStatus() != null, "userinfo_status", form.getUserinfoStatus())
                .eq(StringUtils.hasText(form.getUsername()), "username", form.getUsername())
                .eq(StringUtils.hasText(form.getPhone()), "phone", form.getPhone())
                .eq(form.getStatus() != null, "status", form.getStatus())
                .like(StringUtils.hasText(form.getNickname()), "nickname", form.getNickname())
        );
        List<UserinfoDto> ovList = BeanConvertUtils.coptList(iPage.getRecords(), UserinfoDto.class);
        return R.success(pageInfo.setPageInfo(iPage.getTotal(), ovList));

    }

    @Override
    public void updateStatus(int userinfoId) {
        if (userinfoId == MyConstants.ADMIN_ID) {
            throw new BusinessException("超级管理员禁止更改状态！");
        }
        Userinfo userinfo = this.getById(userinfoId);
        /*重新封装一个专门用来修改状态的实体类*/
        Userinfo updateStatus = new Userinfo();
        updateStatus.setStatus(userinfo.getStatus() == 1 ? 2 : 1);
        updateStatus.setUserinfoId(userinfoId);
        this.updateById(updateStatus);
    }

    @Override
    public void updatePassword(UserinfoPasswordOV form) {
        Userinfo loginInfo = LoginUtils.getLoginUserinfo();
        String oldPasswordMd5 = LoginUtils.createPassword(form.getOldPassword(), loginInfo.getSlat());
        if (!oldPasswordMd5.equals(loginInfo.getPassword())) {
            throw new BusinessException("原密码不正确！");
        }
        Userinfo userinfo = new Userinfo();
        userinfo.setUserinfoId(loginInfo.getUserinfoId());
        userinfo.setSlat(LoginUtils.getSlat());
        userinfo.setPassword(LoginUtils.createPassword(form.getPassword(), userinfo.getSlat()));
        this.updateById(userinfo);
        LoginUtils.logout();
    }

    @Override
    public void register(RegisterOV form) {
        Userinfo searchPhone = this.getUserinfoByPhone(form.getPhone());
        if (searchPhone != null) {
            throw new BusinessException("手机号已注册！");
        }
        Userinfo searchUsername = this.getUserinfoByUsername(form.getUsername());
        if (searchUsername != null) {
            throw new BusinessException("用户名已存在！");
        }
        checkMessageCode(form.getUuid(), form.getPhone(), form.getCode());
        Userinfo userinfo = BeanConvertUtils.copyBean(form, Userinfo.class);
        userinfo.setSlat(LoginUtils.getSlat());
        userinfo.setPassword(LoginUtils.createPassword(form.getPassword(), userinfo.getSlat()));
        userinfo.setNickname(form.getUsername());
        userinfo.setHref(form.getUsername());
        userinfo.setStatus(MyConstants.USERINFO_YIZHUCE);
        userinfo.setAvatar(userinfoDefaultAvatar);
        this.save(userinfo);
    }

    @Override
    public void forget(ForgetOV form) {
        Userinfo searchPhone = this.getUserinfoByPhone(form.getPhone());
        if (searchPhone == null) {
            throw new BusinessException("该用户不存在！");
        }
        checkMessageCode(form.getUuid(), form.getPhone(), form.getCode());
        Userinfo userinfo = BeanConvertUtils.copyBean(form, Userinfo.class);
        userinfo.setSlat(LoginUtils.getSlat());
        userinfo.setPassword(LoginUtils.createPassword(form.getPassword(), userinfo.getSlat()));
        userinfo.setUserinfoId(searchPhone.getUserinfoId());
        this.updateById(userinfo);

        /*根据手机号作为条件*/
//        this.update(userinfo, new QueryWrapper<Userinfo>().eq("phone", userinfo.getPhone()));
    }

    @Override
    public void auth(AuthOV form) {
        Userinfo login = LoginUtils.getLoginUserinfo();
        if (login.getRoleId() == MyConstants.ROLE_ADMIN) {
            throw new BusinessException("无权操作！");
        }
        Userinfo userinfo = BeanConvertUtils.copyBean(form, Userinfo.class);
        userinfo.setUserinfoId(login.getUserinfoId());
        userinfo.setUserinfoStatus(MyConstants.USERINFO_WEIRENZHENG);
        userinfo.setAuthTime(new Date());
        this.updateById(userinfo);
    }

    @Override
    public void exam(ExamOV form) {
        Userinfo login = LoginUtils.getLoginUserinfo();
        if (login.getRoleId() == MyConstants.ROLE_VIP) {
            throw new BusinessException("无权操作！");
        }
        Userinfo userinfo = BeanConvertUtils.copyBean(form, Userinfo.class);
        userinfo.setExamTime(new Date());
        userinfo.setExamUserinfoId(login.getUserinfoId());
        this.updateById(userinfo);
    }

    @Override
    public R getVipInfo() {
        Userinfo userinfo = this.getById(LoginUtils.getVipId());
        if (userinfo == null || userinfo.getUserinfoStatus() != MyConstants.USERINFO_YIRENZHENG || userinfo.getStatus() == 2) {
            throw new BusinessException("用户异常！");
        }
        return R.success(BeanConvertUtils.copyBean(userinfo, UserinfoDto.class));
    }

    @Override
    public R getSelect() {
        List<Userinfo> list = this.list(new QueryWrapper<Userinfo>().eq("userinfo_status", MyConstants.USERINFO_YIRENZHENG));
        return R.success(BeanConvertUtils.coptList(list, UserinfoDto.class));
    }

    private void checkMessageCode(String uuid, String phone, String code) {
        String saveCode = redisTemplate.opsForValue().get(MyConstants.MESSAGE_KEY + uuid + "_" + phone);
        if (saveCode == null || !saveCode.equals(code)) {
            throw new BusinessException("验证码不正确！");
        }
    }

    private Userinfo getUserinfoByUsername(String username) {
        Userinfo userinfo = this.getOne(new QueryWrapper<Userinfo>().eq("username", username));
        return userinfo;
    }

    private Userinfo getUserinfoByPhone(String phone) {
        return this.getOne(new QueryWrapper<Userinfo>().eq("phone", phone));
    }

    private Userinfo getUserinfoByHref(String href) {
        return this.getOne(new QueryWrapper<Userinfo>().eq("href", href));
    }
}




